package com.scada.filter;

import java.util.List;

import org.apache.commons.codec.binary.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import com.scada.hessian.client.impl.RoleVisitorClient;
import com.scada.model.bean.Role;
import com.scada.model.bean.User;
import com.scada.service.PermissionService;
import com.scada.service.RoleService;
import com.scada.service.UserService;


public class SecurityFilter extends AuthorizingRealm {
	
	@Autowired
	private UserService userService;
	
	@Autowired
	private RoleService roleService;
	
	@Autowired
	private PermissionService permissionService;
	
	@Autowired
	private RoleVisitorClient roleVisitorClient;

	/*
	 * (non Javadoc)
	 * @Description: 授权信息
	 * @author: 沈浩
	 * @date: 2016年8月29日 上午11:51:27
	 * @Title: doGetAuthorizationInfo
	 * @param arg0
	 * @return
	 * @see org.apache.shiro.realm.AuthorizingRealm#doGetAuthorizationInfo(org.apache.shiro.subject.
	 * PrincipalCollection)
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		//获得当前登录用户信息
		User LoginUser = (User) principals.fromRealm(getName()).iterator().next();
		//获得当前用户
		User user = userService.securityToLogin(LoginUser.getLoginName(),"");
		//获取用户拥有菜单权限
		if (user != null) {
			//权限信息对象info,用来存放查出的用户的所有的角色（role）及权限（permission）  
            SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();  
            //用户的角色集合  
            info.setRoles(roleService.getAllRolesName(user.getId()));  
            //用户的角色对应的所有权限，如果只使用角色定义访问权限，下面的四行可以不要  
            List<Role> roleList = roleVisitorClient.getAllRolesName(user.getId()); 
            for (Role role : roleList) {  
                info.addStringPermissions(permissionService.getPermissionsCode(role.getId()));  
            }  
            return info;  
        }  
        return null;  
	}
	/*
	 * (non Javadoc)
	 * @Description: 认证信息
	 * @author: 沈浩
	 * @date: 2016年8月29日 上午11:51:41
	 * @Title: doGetAuthenticationInfo
	 * @param arg0
	 * @return
	 * @throws AuthenticationException
	 * @see
	 * org.apache.shiro.realm.AuthenticatingRealm#doGetAuthenticationInfo(org.apache.shiro.authc.
	 * AuthenticationToken)
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
			throws AuthenticationException {
		String userName = String.valueOf(authcToken.getPrincipal());
		if (userName != null && !"".equals(userName)) {
			User user = userService.securityToLogin(userName, new String((char[]) authcToken.getCredentials()));
			if(user == null){
				return null;
			}
			if(!StringUtils.equals(new String((char[]) authcToken.getCredentials()), user.getPassword())){
				new IncorrectCredentialsException();
			}
			if (user != null) {
				AuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(),
						getName());
				SecurityUtils.getSubject().getSession().setTimeout(1000*60*60*2);
				return info;
			}
		}
		return null;
	}

    /**
     * 更新用户授权信息缓存.
     * 
     * @param principal
     */
    public void clearCachedAuthorizationInfo(String principal) {
        SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
        clearCachedAuthorizationInfo(principals);
    }

    /**
     * 清除所有用户授权信息缓存.
     */
    public void clearAllCachedAuthorizationInfo() {
        Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
        if (cache != null) {
            for (Object key : cache.keys()) {
                cache.remove(key);
            }
        }
    }
}
